package com.zeros.myself.utils;

import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

/**
 * 软键盘挡住了输入框 on 2017/12/14.
 * 用法：
 *  1.把AndroidBug5497Workaround类复制到项目中
 *  2.在需要填坑的activity的onCreate方法中添加一句AndroidBug5497Workaround.assistActivity(this)即可。
 */

public class AndroidBug5497Workaround {
    // For more information, see https://code.google.com/p/android/issues/detail?id=5497
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static void assistActivity (Activity activity) {
        new AndroidBug5497Workaround(activity);
    }

    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;

    /**
     * 1)如果Activity是全屏模式，那么android.R.id.content就是占满全部屏幕区域的。
     * 2)如果Activity是普通的非全屏模式，那么android.R.id.content就是占满除状态栏之外的所有区域。
     * 3)其他情况，如Activity是弹窗、或者7.0以后的分屏样式等，android.R.id.content也是弹窗的范围或者分屏所在的半个屏幕——这些情况较少，就暂且不考虑了。
     *
     * 我们经常用的setContentView(View view)/setContent(int layRes)其实就是把我们指定的View或者layRes放到android.R.id.content里面，成为它的子View。
     */
    private AndroidBug5497Workaround(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);//所能控制的区域的根View。
        mChildOfContent = content.getChildAt(0);    //获取到我们用setContentView放进去的View。

        //监听View树变化:ViewTreeObserver->这个对象是一个观察者，专门用以监听当前View树所发生的一些变化。
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                //『软键盘弹出』，则是会触发这个事件
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }


    /**
     * 重设高度
     */
    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();    //获取到的可用

        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();//视图View高度
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;      //比如剩下的软键盘高度

            //去除无谓的干扰。因为能触发OnGlobalLayout事件的原因有很多
            //加上了这个判断之后，只有界面的高度变化超过1/4的屏幕高度，才会进行重新设置高度，基本能保证代码只响应软键盘的弹出。
            if (heightDifference > (usableHeightSansKeyboard/4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }


    /**
     * 界面变化之后，获取"界面的可用高度"-（可以被开发者用以显示内容的高度）。
     */
    private int computeUsableHeight() {
        Rect rect  = new Rect();    //Rect——就是界面除去了标题栏、除去了被软键盘挡住的部分，所剩下的矩形区域
        mChildOfContent.getWindowVisibleDisplayFrame(rect );    //rect.top是状态栏高度，屏幕高度-rect.bottom，是软键盘的高度。
//        return (rect .bottom - rect .top);// H5非全屏模式下：可用高度 = rect.bottom - rect.top
        return rect .bottom;// H5全屏模式下： 可用高度 = return r.bottom
    }

    /**
     * 总结：
     * 1.普通Activity（不带WebView），直接使用adjustpan或者adjustResize
     * 2.如果带WebView：
     *      a) 如果非全屏模式，可以使用adjustResize
     *      b) 如果是全屏模式，则使用AndroidBug5497Workaround进行处理。
     */

}
